from rgblink_cmd import rgblink_cmd
from layer import *
from x14_setting import *



def getDataBlockCheckSumLen(dataBlock , dataLen):
    checkSum = 0
    for i in range(0, dataLen):
        checkSum = (checkSum+dataBlock[i])
    checkSum = checkSum % 256
    return checkSum


class process_cmd:
	def __init__(self):
		self.local_buffer = bytes()
		self.device_set = x14_setting()
		self.interpret_buffer = bytes()
		self.sendSn = 0
		self.receiveSn = 0
		self.cmd = None
		

	def process_cmd(self, receive_buffer):
		self.local_buffer += receive_buffer
		return self._process_cmd(self.local_buffer)
	
	
	def _process_cmd(self, buffer):
		if(len(buffer)<19):
			return None
		cmd = rgblink_cmd.fromReplyBytes(buffer)
		if(cmd == None):
			self.local_buffer = buffer[19:]
			return _process_cmd(self.local_buffer)
		self.local_buffer = cmd.block
		if(cmd.cmd == 0xf1):
			block_len = cmd.data[2]
			block_len += cmd.data[3]<<8
			
			if(block_len > 10000):
				block_len = 0
			#print("block_len", block_len)
			if(len(cmd.block)>=block_len):
				self.local_buffer = cmd.block
				cmd.block = cmd.block[:block_len]
				self.local_buffer = self.local_buffer[block_len:]
			else:
				return None
			
		self.local_buffer = cmd.block
		return cmd

	def _interpret_cmd(self, buffer):
		if(len(buffer)<19):
			return None
		cmd = rgblink_cmd.fromReplyBytes(buffer)
		if(cmd == None):
			index = 0
			for i in range(0, len(buffer)):
				if(buffer[i] == ord(b'<')):
					index = i
					break
			if(index == 0):
				self.interpret_buffer = buffer[19:]
			else:
				self.interpret_buffer = buffer[index:]
			return self._interpret_cmd(self.interpret_buffer)
		
		if(cmd.cmd == 0xf1):
			block_len = cmd.data[2]
			block_len += cmd.data[3]<<8
			
			if(block_len > 10000):
				block_len = 0
			
			#print("block_len", block_len)
			if(len(cmd.block)>=block_len):
				self.interpret_buffer = cmd.block
				cmd.block = cmd.block[:block_len]
				self.interpret_buffer = self.interpret_buffer[block_len:]			
			else:
				return None
		else:	
			self.interpret_buffer = cmd.block	
		return cmd
		
	def interpret_cmd(self, receive_buffer):
		self.interpret_buffer += receive_buffer
		while(len(self.interpret_buffer)>=19):
			cmd = self._interpret_cmd(self.interpret_buffer)
			
			if(cmd == None):
				return None
			#print(cmd)	
			self.receiveSn = cmd.sn
			self.cmd = cmd
			
			if(cmd.cmd == 0xF1):
				self.interpret_0xF1(cmd)
				
			elif(cmd.cmd == 0x68):
				self.interpret_0x68(cmd)
			elif(cmd.cmd == 0x89):
				self.device_set.network.IP_adr[0] = cmd.data[0]
				self.device_set.network.IP_adr[1] = cmd.data[1]
				self.device_set.network.IP_adr[2] = cmd.data[2]
				self.device_set.network.IP_adr[3] = cmd.data[3]
			elif(cmd.cmd == 0x85):
				self.device_set.network.NetMask[0] = cmd.data[0]
				self.device_set.network.NetMask[1] = cmd.data[1]
				self.device_set.network.NetMask[2] = cmd.data[2]
				self.device_set.network.NetMask[3] = cmd.data[3]
			elif(cmd.cmd == 0x8d):
				self.device_set.network.DefGW[0] = cmd.data[0]
				self.device_set.network.DefGW[1] = cmd.data[1]
				self.device_set.network.DefGW[2] = cmd.data[2]
				self.device_set.network.DefGW[3] = cmd.data[3]
			elif(cmd.cmd == 0x8e):
				if(cmd.data[0] == 0x03):
					self.device_set.network.DHCP = cmd.data[1]
				elif(cmd.data[0] == 0x05):
					self.device_set.network.MAC_adr[0] = cmd.data[1]
					self.device_set.network.MAC_adr[1] = cmd.data[2]
					self.device_set.network.MAC_adr[2] = cmd.data[3]
				elif(cmd.data[0] == 0x07):
					self.device_set.network.MAC_adr[3] = cmd.data[1]
					self.device_set.network.MAC_adr[4] = cmd.data[2]
					self.device_set.network.MAC_adr[5] = cmd.data[3]

	def interpret_0xF1(self, cmd):
		#print("interpret_0xF1:", cmd)
		if(cmd.data[2] == 0xff) and (cmd.data[3] == 0xff):
			print("cmd error:", cmd)
			return
			
		dataLen = cmd.data[2]+(cmd.data[3]<<8)
		if(len(cmd.block) != dataLen):
			print("data block len error:" , len(cmd.block), dataLen)
			return
			
		if(dataLen):
			if(cmd.block[dataLen-1] != getDataBlockCheckSumLen(cmd.block, dataLen-1)):
				print("data block checksum err:", cmd)
				print(cmd.block)
		
		if(cmd.data[0] == 0x00):
			#print("layer", cmd.data[1])
			self.device_set.previewView.layer[cmd.data[1]].fromBytes(cmd.block)
			
			
		elif(cmd.data[0] == 0x05):
			output_len = int((len(cmd.block)-1)/8)
			for i in range(0, output_len):
				rect1 = rect.fromBytes(cmd.block[i*8:])
				self.device_set.outputArea[i] = rect1
		elif(cmd.data[0] == 0x09):
			self.device_set.inputSet[cmd.data[1]].fromBytes(cmd.block)
			#print("inputSet", cmd.data[1], inputSet1)
		elif(cmd.data[0] == 0x0a):
			input = cmd.data[1]*4
			for i in range(0, 4):
				self.device_set.inputSource[input+i].type = cmd.block[0+i]
				self.device_set.inputSource[input+i].format = cmd.block[4+i]
				self.device_set.inputSource[input+i].width = cmd.block[8+i*2]+(cmd.block[8+i*2+1]<<8)
				self.device_set.inputSource[input+i].height = cmd.block[16+i*2]+(cmd.block[16+i*2+1]<<8)
				self.device_set.inputSource[input+i].vfreq = cmd.block[24+i]
	def interpret_0x68(self, cmd):
		#print("interpret_0x68", cmd);
		if(cmd.data[0] == 0x01):
			device_type = (cmd.data[1]<<16)+(cmd.data[2]<<8)+cmd.data[3]
			if(self.device_set.device_type != device_type):
				self.device_set.setDeviceType(device_type)
				print("set device type=", hex(device_type))
				
if __name__ == "__main__":
	process_rs232_cmd = process_cmd()
	process_rs232_cmd.interpret_cmd(b'<F00006801800000e9>')
	process_rs232_cmd.interpret_cmd(b'<F000168013200009c>')
	cmd1 = process_rs232_cmd.process_cmd(b'<F000168013200009c>')
	print(cmd1)
	process_rs232_cmd.interpret_cmd(b'<F00948e0301000026><F009589c0a80064ea><F009685ffffff0018><F00978dc0a800018d><F00988e05183080f3><F00998e0700100341>')
	
	